home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / DCPFPKT.C < prev    next >
C/C++ Source or Header  |  1991-08-25  |  15KB  |  462 lines

  1. /* $Header: fio.c,v 1.20 85/04/30 12:57:32 rick Exp $ */
  2. /* %M%   %I%   %E%   (Mathematisch Centrum)  */
  3.  
  4. /*--------------------------------------------------------------------*/
  5. /*    Flow control ("f") protocol.                                    */
  6. /*                                                                    */
  7. /*    This protocol relies on flow control of the data stream.  It    */
  8. /*    is meant for working over links that can (almost) be            */
  9. /*    guaranteed to be errorfree, specifically X.25/PAD links.  A     */
  10. /*    sumcheck is carried out over a whole file only.  If a           */
  11. /*    transport fails the receiver can request retransmission(s).     */
  12. /*    This protocol uses a 7-bit datapath only, so it can be used     */
  13. /*    on links that are not 8-bit transparent.                        */
  14. /*                                                                    */
  15. /*    When using this protocol with an X.25 PAD:  Although this       */
  16. /*    protocol uses no control chars except CR, control chars NULL    */
  17. /*    and ^P are used before this protocol is started; since ^P is    */
  18. /*    the default char for accessing PAD X.28 command mode, be        */
  19. /*    sure to disable that access (PAD par 1).  Also make sure        */
  20. /*    both flow control pars (5 and 12) are set.  The CR used in      */
  21. /*    this proto is meant to trigger packet transmission, hence       */
  22. /*    par 3 should be set to 2; a good value for the Idle Timer       */
  23. /*    (par 4) is 10.  All other pars should be set to 0.              */
  24. /*                                                                    */
  25. /*    Normally a calling site will take care of setting the local     */
  26. /*    PAD pars via an X.28 command and those of the remote PAD via    */
  27. /*    an X.29 command, unless the remote site has a special           */
  28. /*    channel assigned for this protocol with the proper par          */
  29. /*    settings.                                                       */
  30. /*                                                                    */
  31. /*    Author:  Piet Beertema, CWI, Amsterdam, Sep 1984                */
  32. /*                                                                    */
  33. /*    Adapted to uupc 3.0 and THINK C 4.0 by Dave Platt, Jul 1991     */
  34. /*--------------------------------------------------------------------*/
  35.  
  36. /*--------------------------------------------------------------------*/
  37. /*                        System include files                        */
  38. /*--------------------------------------------------------------------*/
  39.  
  40. #include <stdio.h>
  41. #include <time.h>
  42. #include <string.h>
  43.  
  44. /*--------------------------------------------------------------------*/
  45. /*                    UUPC/extended include files                     */
  46. /*--------------------------------------------------------------------*/
  47.  
  48. #include "lib.h"
  49. #include "dcp.h"
  50. #include "dcpfpkt.h"
  51. #include "dcpsys.h"
  52. #include "hostable.h"
  53. #include "security.h"
  54. #include "ssleep.h"
  55. #include "ulib.h"
  56.  
  57. /*--------------------------------------------------------------------*/
  58. /*                              Defines                               */
  59. /*--------------------------------------------------------------------*/
  60.  
  61. #define PKTSIZE   64
  62.  
  63. #ifndef MAXMSGLEN
  64. #define MAXMSGLEN BUFSIZ
  65. #endif MAXMSGLEN
  66.  
  67. /*--------------------------------------------------------------------*/
  68. /*                    Internal function prototypes                    */
  69. /*--------------------------------------------------------------------*/
  70.  
  71. static int fsendresp(int state);
  72.  
  73. /*--------------------------------------------------------------------*/
  74. /*                          Global variables                          */
  75. /*--------------------------------------------------------------------*/
  76.  
  77. static int chksum;
  78.  
  79. /*--------------------------------------------------------------------*/
  80. /*    f o p e n p k                                                   */
  81. /*                                                                    */
  82. /*    Open "f" protocol to other system                               */
  83. /*--------------------------------------------------------------------*/
  84.  
  85. int fopenpk()
  86. {
  87.    flowcontrol(TRUE);
  88.     pktsize = PKTSIZE;
  89.    ssleep(2); /* Give peer time to perform corresponding port setup */
  90.    return OK;
  91. } /* fopenpk */
  92.  
  93. /*--------------------------------------------------------------------*/
  94. /*    f c l o s e p k                                                 */
  95. /*                                                                    */
  96. /*    Shutdown "f" procotol with other system                         */
  97. /*--------------------------------------------------------------------*/
  98.  
  99. fclosepk()
  100. {
  101.    flowcontrol(FALSE);
  102.    return OK;
  103. } /* fclosepk */
  104.  
  105. /*--------------------------------------------------------------------*/
  106. /*    f w r m s g                                                     */
  107. /*                                                                    */
  108. /*    Send a control message to remote system with "f" procotol       */
  109. /*--------------------------------------------------------------------*/
  110.  
  111. int fwrmsg(char *str)
  112. {
  113.    char bufr[MAXMSGLEN];
  114.    char *s = bufr;
  115.  
  116.    while (*str)
  117.       *s++ = *str++;
  118.    if (*(s-1) == '\n')
  119.       s--;
  120.    *s++ = '\r';
  121.    (void) swrite(bufr, s - bufr);
  122.    return OK;
  123. } /* fwrmsg */
  124.  
  125. /*--------------------------------------------------------------------*/
  126. /*    f r d m s g                                                     */
  127. /*                                                                    */
  128. /*    Read a control message from remote host with "f" protocol       */
  129. /*--------------------------------------------------------------------*/
  130.  
  131. int frdmsg(char *str)
  132. {
  133.    char *smax;
  134.    char *s = str;
  135.  
  136.    smax = s + MAXPACK - 1;
  137.    for (;;) {
  138.       if (sread(s, 1, PacketTimeout) <= 0)
  139.       {
  140.          printmsg(0,"frdmsg: timeout reading message");
  141.          *s++ = '\0';
  142.          goto msgerr;
  143.       }
  144.       if (*s == '\r')
  145.          break;
  146.       if (*s < ' ')
  147.          continue;
  148.       if (s++ >= smax)
  149.       {
  150.          printmsg(0,"frdmsg: buffer overflow");
  151.          *--s = '\0';
  152.          goto msgerr;
  153.       } /* if (s++ >= smax) */
  154.    }
  155.    *s = '\0';
  156.    return OK;
  157.  
  158. msgerr:
  159.    printmsg(0,"frdmsg: Message received \"%s\"", str);
  160.    return FAILED;
  161. } /* frdmsg */
  162.  
  163. /*--------------------------------------------------------------------*/
  164. /*    f g e t p k t                                                   */
  165. /*                                                                    */
  166. /*    Receive an "f" protocol packet of data from the other system    */
  167. /*--------------------------------------------------------------------*/
  168.  
  169. int fgetpkt(char *packet, int *bytes)
  170. {
  171.    char *op, c, *ip;
  172.    int sum, len, left;
  173.    char buf[5], tbuf[1];
  174.    int i;
  175.    static char special = 0;
  176.    static boolean eof = FALSE;
  177.  
  178. /*--------------------------------------------------------------------*/
  179. /*                    Handle EOF on previous call                     */
  180. /*--------------------------------------------------------------------*/
  181.  
  182.    if ( eof )
  183.    {
  184.       eof = FALSE;
  185.       printmsg(0,"fgetpkt: EOF from other host");
  186.       *bytes = 0;
  187.       if (fsendresp(OK) == OK)
  188.          return OK;
  189.       else
  190.          return FAILED;
  191.    } /* if ( eof ) */
  192.  
  193.    left = pktsize;
  194.    op = packet;
  195.    sum = chksum;
  196.  
  197. /*--------------------------------------------------------------------*/
  198. /*                     Loop to fill up one packet                     */
  199. /*--------------------------------------------------------------------*/
  200.  
  201.    do {
  202.       ip = tbuf;
  203.       len = sread(ip, 1, PacketTimeout); /* single-byte reads for now */
  204.       if (len == 0) {
  205.          printmsg(0,"fgetpkt: Timeout after %d seconds", PacketTimeout);
  206.          return FAILED;               /* Fail if timed out */
  207.       }
  208.       if ((*ip &= 0177) >= '\172') {
  209.          if (special) {
  210.             special = 0;
  211.             if (*ip++ != '\176')
  212.             {
  213.                printmsg(0,"fgetpkt: error: Did not expect character\
  214. ^%c (x%02x)",
  215.                   (char) (*(ip-1) + 'A') , (int) *(ip-1));
  216.                goto dcorr;
  217.             }
  218.             len = 0;
  219.  
  220.             while (len < 5) {
  221.                i = sread(&buf[len], 5 - len, PacketTimeout);
  222.                if (i == 0) {
  223.                   printmsg(0,
  224.                      "fgetpkt: Timeout reading %d chars after %d seconds",
  225.                               5 - len, PacketTimeout);
  226.                   goto dcorr;
  227.                }
  228.                len += i;
  229.             }
  230.  
  231.             printmsg(6, "fgetpkt: buf=|%.*s|", len , packet);
  232.             if (buf[4] != '\r')
  233.             {
  234.                printmsg(0,"fgetpkt: error: Expected carriage return, \
  235. not %s%c (x%02x)",
  236.                   (buf[4] < ' ') ? "^" : "" ,
  237.                   (char) (buf[4] + ((buf[4] < ' ') ? 'A' : 0)),
  238.                   (int) buf[4]);
  239.                goto dcorr;
  240.             }
  241.             sscanf(buf, "%4x", &chksum);
  242.             *bytes = op - packet;
  243.             if (chksum == sum) {
  244.                eof = TRUE;
  245.                printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  246.                return OK;
  247.             } else {
  248.                printmsg(0, "fgetpkt: Checksum mismatch, told %04x, calc %04x",
  249.                             chksum, sum);
  250.                fsendresp(RETRY);
  251.                return RETRY;
  252.             }
  253.          }
  254.          special = *ip++;
  255.       } else {
  256.          if (*ip < '\040') {
  257.             printmsg(0,"fgetpkt: error: got control character ^%c (%x)",
  258.                   (char) (*ip + 'A') , (int) *ip);
  259.             goto dcorr;
  260.          }
  261.  
  262.          switch (special) {
  263.             case 0:
  264.                c = (char) (*ip++);
  265.                break;
  266.             case '\172':
  267.                c = (char) (*ip++ - 0100);
  268.                break;
  269.             case '\173':
  270.                c = (char) (*ip++ + 0100);
  271.                break;
  272.             case '\174':
  273.                c = (char) (*ip++ + 0100);
  274.                break;
  275.             case '\175':
  276.                c = (char) (*ip++ + 0200);
  277.                break;
  278.             case '\176':
  279.                c = (char) (*ip++ + 0300);
  280.                break;
  281.          }
  282.  
  283.          *op++ = c;
  284.          left --;
  285.          if (sum & 0x8000) {
  286.             sum <<= 1;
  287.             sum++;
  288.          } else
  289.             sum <<= 1;
  290.          sum += c & 0377;
  291.          sum &= 0xffff;
  292.          special = 0;
  293.       }
  294.    } while (left > 0);
  295.  
  296. /*--------------------------------------------------------------------*/
  297. /*            The packet is full of data, return to caller            */
  298. /*--------------------------------------------------------------------*/
  299.  
  300.    *bytes = pktsize;
  301.    printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  302.    chksum = sum;
  303.    return OK;
  304.  
  305. /*--------------------------------------------------------------------*/
  306. /*            The data is corrupt; flush the incoming file            */
  307. /*--------------------------------------------------------------------*/
  308.  
  309. dcorr:
  310.    printmsg (0, "Data corrupted, skipping to EOF");
  311.  
  312.    len = 1;
  313.    while (len)
  314.       len = sread(packet, 1, PacketTimeout);
  315.  
  316.    fsendresp(RETRY);
  317.    return RETRY;
  318. } /* fgetpkt */
  319.  
  320. /*--------------------------------------------------------------------*/
  321. /*    f s e n d p k t                                                 */
  322. /*                                                                    */
  323. /*    Send an "f" protocol packet to the other system                 */
  324. /*--------------------------------------------------------------------*/
  325.  
  326. fsendpkt(char *ip, int len)
  327. {
  328.    char *op;
  329.    int sum, nl;
  330.    int ret;
  331.    char obuf[MAXPACK * 2];
  332.    op = obuf;
  333.    nl = 0;
  334.    sum = chksum;
  335.    if (len == 0)
  336.    {
  337.       printmsg(0,"fsendpkt: Internal error: zero length for packet");
  338.       return FAILED;
  339.    }
  340.    do {
  341.       if (sum & 0x8000) {
  342.          sum <<= 1;
  343.          sum++;
  344.       } else
  345.          sum <<= 1;
  346.       sum += *ip & 0377;
  347.       sum &= 0xffff;
  348.       if (*ip & 0200) {
  349.          *ip &= 0177;
  350.          if (*ip < 040) {
  351.             *op++ = '\174';
  352.             *op++ = (char) (*ip++ + 0100);
  353.          } else
  354.          if (*ip <= 0171) {
  355.             *op++ = '\175';
  356.             *op++ = *ip++;
  357.          }
  358.          else {
  359.             *op++ = '\176';
  360.             *op++ = (char) (*ip++ - 0100);
  361.          }
  362.          nl += 2;
  363.       } else {
  364.          if (*ip < 040) {
  365.             *op++ = '\172';
  366.             *op++ = (char) (*ip++ + 0100);
  367.             nl += 2;
  368.          } else
  369.          if (*ip <= 0171) {
  370.             *op++ = *ip++;
  371.             nl++;
  372.          } else {
  373.             *op++ = '\173';
  374.             *op++ = (char) (*ip++ - 0100);
  375.             nl += 2;
  376.          }
  377.       }
  378.    } while (--len > 0);
  379.    chksum = sum;
  380.    ret = swrite(obuf, nl);
  381.    if ( ret == nl )
  382.       return OK;
  383.    else
  384.       return FAILED;
  385. } /* fsendpkt */
  386.  
  387. /*--------------------------------------------------------------------*/
  388. /*    f f i l e p k t                                                 */
  389. /*                                                                    */
  390. /*    Prepare for processing an "f" procotol file transfer            */
  391. /*--------------------------------------------------------------------*/
  392.  
  393. int ffilepkt( void)
  394. {
  395.    chksum = 0xffff;
  396.    printmsg(3,"ffilepkt: Checksum reset");
  397.    return OK;
  398. } /* ffilepkt */
  399.  
  400. /*--------------------------------------------------------------------*/
  401. /*    f e o f                                                         */
  402. /*                                                                    */
  403. /*    Transmit "f" protocol end of file to the other system           */
  404. /*--------------------------------------------------------------------*/
  405.  
  406. int feofpkt( void )
  407. {
  408.    char ibuf[MAXMSGLEN];
  409.    printmsg(0,"feofpkt: sending EOF");
  410.    sprintf(ibuf, "\176\176%04x", chksum);
  411.    fwrmsg(ibuf);
  412.    printmsg(2,"--> %s", ibuf);
  413.  
  414.    if (frdmsg(ibuf) == FAILED)
  415.       return FAILED;
  416.  
  417.    printmsg(2,"<-- %s",ibuf);
  418.  
  419.    switch(*ibuf)
  420.    {
  421.       case 'R':
  422.          return RETRY;
  423.  
  424.       case 'G':
  425.          return OK;
  426.  
  427.       default:
  428.          return FAILED;
  429.  
  430.    } /* switch */
  431.  
  432. } /* feofpkt */
  433.  
  434. /*--------------------------------------------------------------------*/
  435. /*    f s e n d r e s p                                               */
  436. /*                                                                    */
  437. /*    Send result to a file transfer to other host                    */
  438. /*--------------------------------------------------------------------*/
  439.  
  440. static int fsendresp(int state)
  441. {
  442.    char *s;
  443.    switch (state)
  444.    {
  445.       case OK:
  446.          s = "G";
  447.          break;
  448.  
  449.       case RETRY:
  450.          s = "R";
  451.          break;
  452.  
  453.       default:
  454.          s = "Q";
  455.          break;
  456.    }
  457.  
  458.    printmsg(2,"--> %s", s);
  459.    return fwrmsg(s);
  460.  
  461. } /* fsendresp */
  462.